<!--
*@Author: zt
*@Description: 角色权限管理
*@Date: 2024-08-26
-->
<template>
  <a-layout class="f-h-100 u-role-power">
    <u-collapsed-sider class="f-padding-6" width="280px" :canExpand="false">
      <div class="s-bg-white">
        <div class="u-modle-title">角色</div>
        <div class="u-tool-bar" style="padding: 6px 12px">
          <a-form :model="searchF" label-width="72px">
            <a-form-item label="角色类型" class="f-margin-b0">
              <u-select
                v-model:value="searchF.model.rolestype"
                :options="ROLE_TYPE"
                :allowClear="false"
                @change="getRolesData"
              />
            </a-form-item>
          </a-form>
        </div>
        <div style="height: calc(100% - 96px)">
          <u-tree
            :treeData="roles.roleData"
            class="u-role-tree"
            :showSearch="false"
            :fieldNames="{
              title: 'rolename',
              key: 'keyid',
              children: 'children',
            }"
            @select="roleClick"
          />
        </div>
      </div>
    </u-collapsed-sider>

    <!-- 模块 -->
    <div class="s-bg-white" style="margin-left: 12px; width: 320px">
      <div class="u-modle-title">模块</div>
      <div class="f-flex-row u-tool-bar">
        <u-icon-button itype="save" @click="featureSave">保存</u-icon-button>
        <span class="u-show-label">{{ roles.roleSelectName }}</span>
      </div>
      <div style="height: calc(100% - 96px)">
        <u-tree
          :treeData="roles.featureData"
          multiple
          checkable
          :loading="roles.loadingFeatuer"
          ref="featureTree"
          :showSearch="false"
          :fieldNames="{ title: 'name', key: 'keyid', children: 'children' }"
          v-model:expandedKeys="featureExpands"
          v-model:checkedKeys="roles.featureDefaultKeys"
          @check="featureCheck"
        />
      </div>
    </div>

    <!-- 用户 -->
    <div
      class="s-bg-white"
      style="
        margin-left: 12px;
        width: calc(100% - 24px - 320px - 270px);
        min-width: 240px;
      "
    >
      <div class="u-modle-title">用户</div>
      <div class="f-flex-row u-tool-bar">
        <u-icon-button itype="save" @click="userSave">保存</u-icon-button>
        <a-tree-select
          v-model:value="roles.fkunitsid"
          :treeData="roles.unitData"
          :fieldNames="{ label: 'name', value: 'keyid', children: 'children' }"
          style="margin-left: 12px; width: 200px"
          :allowClear="false"
          @change="getUserData"
        />
      </div>
      <div style="height: calc(100% - 96px)">
        <u-tree
          :treeData="roles.userData"
          multiple
          checkable
          :showSearch="false"
          :loading="roles.lodingUser"
          v-model:checkedKeys="roles.userDefaultKeys"
          v-model:expandedKeys="userDefaultExpandKeys"
          :fieldNames="{ title: 'name', key: 'keyid', children: 'children' }"
          ref="userTree"
          @check="userCheck"
        />
      </div>
    </div>
  </a-layout>
</template>
<script lang="ts" setup>
// import Edit from './Edit.vue'
import * as enmuService from '@/service/enum/index';
import * as unitService from '@/service/system/unit/index';
import * as menuService from '@/service/system/menu/index';
import * as roleService from '@/service/system/role/index';
import * as userService from '@/service/system/user/index';
import * as role_powerService from '@/service/system/role_power/index';
import { formatTreeDis } from '@/util/format.ts'
import { computed, nextTick, onMounted, reactive, ref } from 'vue';
import { alertC, nullC, numberC } from '@/util/common';
import { storeToRefs } from 'pinia';
import { useBaseStore } from '@/store';
import { useDisTreeParent } from '@/hooks/useTree';
import { otherEventBus } from '@/util/eventBus';
// import { createNamespacedHelpers } from 'vuex'

// const { mapGetters } = createNamespacedHelpers("loginStore")

const { ROLE_TYPE } = storeToRefs(useBaseStore());
const searchF = reactive({
  model: {
    rolestype: null,
    rolename: null,
    isuse: 1,
  },
  current: 1,
  order: 'descending',
  sort: 'rolecode',
  size: -1,
});

const roles = reactive<any>({
  roleTypes: [],

  roleSelect: {},
  roleSelectName: '',
  roleData: [],

  loadingFeatuer: false,
  featureSelect: [],
  featureData: [],
  featureDefaultKeys: [],

  lodingUser: false,
  fkunitsid: '',
  unitData: [],
  userSelect: [],
  userDefaultKeys: [],
  userData: [],
  roleUserKeyids: [], // 角色所拥有的用户id
});

const featureExpands = ref<string[]>([]);
const userDefaultExpandKeys = ref<string[]>([]);

// 所有父级所包含的子级
const allMenuKeys = ref<string[]>([]);

onMounted(() => {
  getEnum();
  getMenuData();
  getUnitData();
});

// 获取枚举数据
const getEnum = () => {
  roles.roleTypes.splice(0, roles.roleTypes.length, ...ROLE_TYPE.value);
  searchF.model.rolestype = roles.roleTypes.length == 0 ? null : numberC(roles.roleTypes[0]['id'] + '');
  getRolesData();
};

const featureTree = ref();
const userTree = ref();

// 获取根据角色类型获取角色数据
const getRolesData = () => {
  featureExpands.value = [];
  roles.featureDefaultKeys.splice(0, roles.featureDefaultKeys.length);

  roles.userDefaultKeys.splice(0, roles.userDefaultKeys.length);
  userDefaultExpandKeys.value = [];

  roles.roleSelect = {};
  let tform = JSON.parse(JSON.stringify(searchF));
  tform.model.rolestype = nullC(tform.model.rolestype, null);

  roles.loadingFeatuer = true;
  roleService
    .rolePage(tform)
    .then(res => {
      roles.loadingFeatuer = false;
      if (res.code == 0) {
        roles.roleData.splice(0, roles.roleData.length, ...res.data.records);
      }
    })
    .catch(() => (roles.loadingFeatuer = false));
};

// 角色树形点击
const roleClick = (data, { node }) => {
  featureExpands.value = [];
  roles.featureDefaultKeys.splice(0, roles.featureDefaultKeys.length);

  roles.userDefaultKeys.splice(0, roles.userDefaultKeys.length);
  userDefaultExpandKeys.value = [];

  roles.roleSelect = node;
  roles.roleData.map(e => {
    if (e.keyid == node.keyid) {
      roles.roleSelectName = e.rolename;
    }
  });

  // 查询相关联的功能模块
  roles.loadingFeatuer = true;
  role_powerService
    .getRoleModules(node.keyid)
    .then(res => {
      roles.loadingFeatuer = false;
      if (res.code == 0) {
        const keyisd = res.data.map(item => item.fkmodid);

        const filterKeyids = filterNonParentKeid(keyisd);

        roles.featureDefaultKeys.splice(
          0,
          roles.featureDefaultKeys.length,
          ...filterKeyids
        );

        roles.featureSelect.splice(
          0,
          roles.featureSelect.length,
          ...filterKeyids
        );
        featureExpands.value = roles.featureData
          .filter(
            i => keyisd.includes(i['keyid']) && (i['children'] || []).length > 0
          )
          .map(i => i.keyid);
      }
    })
    .catch(() => {
      roles.loadingFeatuer = false;
    });

  // 查询相关联的用户
  roles.lodingUser = true;
  role_powerService
    .getRoleUser(node.keyid)
    .then(res => {
      roles.lodingUser = false;
      if (res.code == 0) {
        const keyisd = res.data.map(item => item.fkuserid);
        roles.userDefaultKeys.splice(
          0,
          roles.userDefaultKeys.length,
          ...keyisd
        );

        roles.userSelect.splice(0, roles.userSelect.length, ...keyisd);
        roles.roleUserKeyids.splice(0, roles.roleUserKeyids.length, ...keyisd);

        userDefaultExpandKeys.value = getParentIdById(roles.userData, keyisd);
      }
    })
    .catch(() => {
      roles.lodingUser = false;
    });
};

// 获取功能模块数据
const getMenuData = () => {
  roles.loadingFeatuer = true;
  menuService
    .tree('')
    .then(res => {
      roles.loadingFeatuer = false;
      if (res.code == 0 && res.data) {
        roles.featureData.splice(0, roles.featureData.length, ...res.data);

        allMenuKeys.value = [];
        getMenuKeyids(res.data);
      }
    })
    .catch(() => (roles.loadingFeatuer = false));
};

// 功能树形的选择事件
const featureCheck = checkedKeys => {
  roles.featureSelect.splice(0, roles.featureSelect.length, ...checkedKeys);
};

// 角色授予功能保存
const featureSave = () => {
  if (!roles.roleSelect['keyid']) {
    alertC('请先选择角色!', 'warning');
    return;
  }

  if (roles.featureSelect.length == 0) {
    alertC('请先选择功能!', 'warning');
    return;
  }

  const form = {
    fkmodid: roles.featureSelect,
    fkroleid: roles.roleSelect['keyid'],
  };

  role_powerService
    .saveRoleModules(form)
    .then(res => {
      if (res.code == 0) {
        alertC('修改成功,请刷新页面获取最新的菜单！', 'success');
        otherEventBus.emit('updateMenu');
      } else {
        alertC(res.msg, 'warning');
      }
    })
    .catch(() => {});
};

// 获取单位数据
const getUnitData = () => {
  unitService
    .validTree('')
    .then(res => {
      if (res.code == 0 && res.data) {
        roles.unitData.splice(0, roles.unitData.length, ...res.data);
        roles.fkunitsid = roles.unitData[0]['keyid'];
        getUserData();
      }
    })
    .catch(() => {});
};

// 生成所有菜单keyid
const getMenuKeyids = data => {
  data.forEach(item => {
    allMenuKeys.value.push(item.keyid);
    if ((item.children || []).length != 0) {
      getMenuKeyids(item.children);
    }
  });
};

// 过滤掉选中数据中父级选中但未选中子级的父级id
const filterNonParentKeid = keyids => {
  let unSelKeyids = allMenuKeys.value.filter(keyid => !keyids.includes(keyid));
  const currentItems = getParentIdById(roles.featureData, unSelKeyids, 'item');
  const parents = getParentIdById(
    roles.featureData,
    currentItems.map(i => i.fkparentid),
    'item'
  );
  return keyids.filter(
    i => !parents.map(o => o.keyid).includes(i) && i != '999'
  );
};

// 用户选中事件
const userCheck = keys => {
  roles.userSelect.splice(0, roles.userSelect.length, ...keys);
};

// 单位change事件获取用户数据
const getUserData = () => {
  roles.userSelect = [];
  roles.lodingUser = true;
  userService
    .tree(roles.fkunitsid)
    .then(res => {
      roles.lodingUser = false;
      if (res.code == 0) {
        const tdata = res.data;
        roles.userData.splice(0, roles.userData.length, ...tdata);
      }
    })
    .catch(() => (roles.lodingUser = false));
};

// 角色赋予人员保存
const userSave = () => {
  if (!roles.roleSelect['keyid']) {
    alertC('请先选择角色!', 'warning');
    return;
  }

  if (roles.userSelect.length == 0) {
    alertC('请先选择用户!', 'warning');
    return;
  }

  let deptIds = roles.userData.map(i => i.keyid);
  let tUserIds = roles.userSelect.filter(i => !deptIds.includes(i));

  const form = {
    fkuserid: tUserIds,
    fkroleid: roles.roleSelect['keyid'],
  };

  roles.lodingUser = true;
  role_powerService
    .saveRoleUser(form)
    .then(res => {
      roles.lodingUser = false;
      if (res.code == 0) {
        alertC(res.msg, 'success');
      } else {
        alertC(res.msg, 'warning');
      }
    })
    .catch(() => (roles.lodingUser = false));
};

// 根据keyid获取父级id
const getParentIdById = (data1, keyids = [], resultType = 'keyid') => {
  let data = [];
  const get = tdata => {
    tdata.forEach(item => {
      if (keyids.includes(item['keyid'])) {
        data.push(resultType == 'keyid' ? item['fkparentid'] : item);
      }
      if (item.children) {
        get(item.children);
      }
    });
  };

  get(data1);
  return data;
};
</script>
<style lang="scss">
.u-role-power {
  overflow: auto;
  .u-role-tree {
    .u-tree-title {
      border-bottom: 1px solid #eee;
    }
  }
  .u-modle-title {
    height: 40px;
    padding-left: 10px;
    font-size: 18px;
    line-height: 40px;
  }
  .u-tool-bar {
    padding: 10px;
    border: 1px solid #eee;
    border-left: none;
    border-right: none;
    align-items: center;
    .u-show-label {
      margin-left: 12px;
      font-size: 14px;
    }
  }
}
</style>
